package com.ruoyi.business.service.impl;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.Page;
import com.ruoyi.business.domain.CarPackageAudit;
import com.ruoyi.business.domain.HistoricActivity;
import com.ruoyi.business.domain.ServiceItem;
import com.ruoyi.business.mapper.CarPackageAuditMapper;
import com.ruoyi.business.service.ICarPackageAuditService;
import com.ruoyi.business.service.IDefinitionNodeService;
import com.ruoyi.business.service.IProcessService;
import com.ruoyi.business.service.IServiceItemService;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.page.PageDomain;
import com.ruoyi.common.core.page.TableSupport;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.mapper.SysUserMapper;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.apache.commons.lang3.BooleanUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * 审核列表Service业务层处理
 *
 * @author wolfcode
 * @date 2021-07-20
 */
@Service
public class CarPackageAuditServiceImpl implements ICarPackageAuditService {
    @Autowired
    private CarPackageAuditMapper carPackageAuditMapper;
    @Autowired
    private IProcessService processService;
    @Autowired
    private IServiceItemService serviceItemService;
    @Autowired
    private IDefinitionNodeService definitionNodeService;
    @Autowired
    private SysUserMapper sysUserMapper;

    /**
     * 查询审核列表
     *
     * @param id 审核列表ID
     * @return 审核列表
     */
    @Override
    public CarPackageAudit selectCarPackageAuditById(Long id) {
        return carPackageAuditMapper.selectCarPackageAuditById(id);
    }

    /**
     * 查询审核列表列表
     *
     * @param carPackageAudit 审核列表
     * @return 审核列表
     */
    @Override
    public List<CarPackageAudit> selectCarPackageAuditList(CarPackageAudit carPackageAudit) {
        List<CarPackageAudit> carMaintenanceInfos = carPackageAuditMapper.selectCarPackageAuditList(carPackageAudit);
        for (CarPackageAudit audit : carMaintenanceInfos) {
            audit.setServiceItem(JSON.parseObject(audit.getServiceItemInfo(), ServiceItem.class));
            // 根据流程实例id查询当前任务
            Task currentTask = processService.getTaskByProcessInstanceId(audit.getInstanceId());
            if (currentTask != null) {
                audit.setTaskId(currentTask.getId());
                audit.setTaskName(currentTask.getName());
            } else {
                audit.setTaskName("审批结束");
            }
        }
        return carMaintenanceInfos;
    }

    /**
     * 新增审核列表
     *
     * @param carPackageAudit 审核列表
     * @return 结果
     */
    @Override
    public int insertCarPackageAudit(CarPackageAudit carPackageAudit) {
        carPackageAudit.setCreateTime(DateUtils.getNowDate());
        return carPackageAuditMapper.insertCarPackageAudit(carPackageAudit);
    }

    /**
     * 修改审核列表
     *
     * @param carPackageAudit 审核列表
     * @return 结果
     */
    @Override
    public int updateCarPackageAudit(CarPackageAudit carPackageAudit) {
        return carPackageAuditMapper.updateCarPackageAudit(carPackageAudit);
    }

    /**
     * 删除审核列表对象
     *
     * @param ids 需要删除的数据ID
     * @return 结果
     */
    @Override
    public int deleteCarPackageAuditByIds(String ids) {
        return carPackageAuditMapper.deleteCarPackageAuditByIds(Convert.toStrArray(ids));
    }

    /**
     * 删除审核列表信息
     *
     * @param id 审核列表ID
     * @return 结果
     */
    @Override
    public int deleteCarPackageAuditById(Long id) {
        return carPackageAuditMapper.deleteCarPackageAuditById(id);
    }

    @Override
    @Transactional
    public void cancelApply(String instanceId, Long carPackageAuditId) {
        //把快照表的信息，更新状态为撤销状态 , 审核人设置为空
        CarPackageAudit carPackageAudit = carPackageAuditMapper.selectCarPackageAuditById(carPackageAuditId);
        carPackageAudit.setStatus(CarPackageAudit.STATUS_CANCEL);
        carPackageAudit.setAuditors("");

        carPackageAuditMapper.updateCarPackageAudit(carPackageAudit);
        //获取服务项,更新审核状态为初始化
        ServiceItem serviceItem = JSON.parseObject(carPackageAudit.getServiceItemInfo(), ServiceItem.class);
        serviceItem.setAuditStatus(ServiceItem.AUDITSTATUS_INIT);//审核状态为初始化
        serviceItemService.updateServiceItemNoCondition(serviceItem); //重写方法,之前的方法会判断状态,如果处于审核中是不允许修改的
        //执行此方法后未审批的任务 act_ru_task 会被删除，流程历史 act_hi_taskinst 不会被删除，并且流程历史的状态为finished完成
        //删除流程实例
        processService.deleteProcessInstance(instanceId);
    }

    @Override
    public List<CarPackageAudit> findTodoList(CarPackageAudit carPackageAudit) {
        //1.查询当前登录用户关于汽车审核所有的待办任务总数
        long count = processService.selectTodoTaskCount(CarPackageAudit.DEFINITION_KEY, ShiroUtils.getUserId().toString());
        if (count > 0) {
            //如果符合条件的记录数大于0,才进行集合的查询
            PageDomain pageDomain = TableSupport.buildPageRequest();
            Integer pageNum = pageDomain.getPageNum();
            Integer pageSize = pageDomain.getPageSize();
            //2.查询当前登录用户关于汽车审核所有的待办任务集合
            List<Task> taskList = processService
                    .selectTodoTaskList(CarPackageAudit.DEFINITION_KEY, //哪个流程
                            ShiroUtils.getUserId().toString(),//查询谁的任务
                            (pageNum - 1) * pageSize,//分页中起始位置
                            pageSize);//查询多少条
            //3.遍历待办任务,查询对应的CarPackAgeAudit
            // 需要返回给前台的数据
            List<CarPackageAudit> resultList = new ArrayList<>();
            CarPackageAudit audit;
            for (Task task : taskList) {
                ProcessInstance processInstance = processService
                        .getProcessInstanceById(task.getProcessInstanceId());
                String businessKey = processInstance.getBusinessKey();
                audit = carPackageAuditMapper.selectCarPackageAuditById(Long.parseLong(businessKey));
                audit.setServiceItem(JSON.parseObject(audit.getServiceItemInfo(), ServiceItem.class));
                audit.setTaskName(task.getName());
                audit.setTaskId(task.getId());
                resultList.add(audit);
            }
            //封装成Page对象返回
            Page<CarPackageAudit> list = new Page<>();
            list.setTotal(count);
            list.setPageNum(pageNum);
            list.setPageSize(pageSize);
            list.addAll(resultList);
            return list;
        } else {
            //如果总数为0,返回空集合回去
            return Collections.EMPTY_LIST;
        }
    }

    @Override
    @Transactional
    public void complete(String taskId, String auditStatus, String comment) {
        boolean auditStatusBoolean = BooleanUtils.toBoolean(auditStatus);
        String commentStr = auditStatusBoolean ? "【同意】" : "【拒绝】";
        if (StringUtils.isNotEmpty(comment)) {
            commentStr += comment;
        }
        //1.根据任务Id查询任务对象
        Task task = processService.getTaskByTaskId(taskId);
        //这步需要放在前面
        ProcessInstance instance = processService.getProcessInstanceById(task.getProcessInstanceId());
        //3.添加批注,设置流程变量,领取任务,完成任务
        processService.claimAndCompleteTask(task, ShiroUtils.getUserId().toString(), auditStatusBoolean, commentStr);
        //4.完成任务后查询流程实例的下一个任务.
        Task nextTask = processService.getTaskByInstanceId(task.getProcessInstanceId());

        CarPackageAudit audit = carPackageAuditMapper.selectCarPackageAuditById(Long.parseLong(instance.getBusinessKey()));
        //5.判断流程是否已经结束
        if (nextTask != null) {
            //5.1任务没有结束
            //需要指定下一个任务的候选人
            List<String> auditors = new ArrayList<>();
            //判断审核通过和是审核拒绝
            if (auditStatusBoolean) {
                String taskDefinitionKey = nextTask.getTaskDefinitionKey();
                List<SysUser> auditorIdList = definitionNodeService.queryByTaskDefinitionKey(taskDefinitionKey);
                for (SysUser auditor : auditorIdList) {
                    processService.addCandidateUser(nextTask, auditor.getUserId());
                    auditors.add(auditor.getUserName());
                }
            } else {
                String userId = audit.getCreateBy();
                auditors.add(audit.getCreateByName());
                processService.addCandidateUser(nextTask, Long.parseLong(userId));
                audit.setStatus(CarPackageAudit.STATUS_REJECT);
            }
            audit.setAuditors(JSON.toJSONString(auditors));
            carPackageAuditMapper.updateCarPackageAudit(audit);
        } else {
            //5.2 任务结束
            //修改CarPackageAudit的状态,审核人字段设置为空
            audit.setAuditors("");
            audit.setStatus(CarPackageAudit.STATUS_PASS);
            carPackageAuditMapper.updateCarPackageAudit(audit);
            //修改养修明细项审核状态
            ServiceItem serviceItem = JSON.parseObject(audit.getServiceItemInfo(), ServiceItem.class);
            serviceItem.setAuditStatus(ServiceItem.AUDITSTATUS_APPROVED);
            serviceItemService.updateServiceItemNoCondition(serviceItem);
        }
    }

    @Override
    @Transactional
    public void updateServiceItem(Long carPackageAuditId, ServiceItem serviceItem) {
        serviceItemService.updateServiceItemNoCondition(serviceItem);
        CarPackageAudit carPackageAudit = carPackageAuditMapper.selectCarPackageAuditById(carPackageAuditId);
        carPackageAudit.setServiceItemInfo(JSON.toJSONString(serviceItem));
        carPackageAuditMapper.updateCarPackageAudit(carPackageAudit);
    }

    @Override
    @Transactional
    public void reApply(String taskId, Long carPackageAuditId) {
        // 添加批注,领取任务,完成任务
        Task task = processService.getTaskByTaskId(taskId);
        // 设置新的流程变量
        // 根据传入carPackageAuditId查询carPackageAuditId对象 ,更新状态为:审核中
        CarPackageAudit audit = carPackageAuditMapper.selectCarPackageAuditById(carPackageAuditId);
        ServiceItem serviceItem = JSON.parseObject(audit.getServiceItemInfo(), ServiceItem.class);
        processService.setVariable(task.getId(), "money", serviceItem.getDiscountPrice().longValue());
        // 完成任务
        processService.claimAndCompleteTask(task, ShiroUtils.getUserId().toString(), "重新申请");
        // 找到查询下一个节点,查询对应的候选人,给任务添加候选人
        // 根据流程实例ID查询当前流程正在走的节点(任务)
        Task nextTask = processService.getTaskByProcessInstanceId(task.getProcessInstanceId());
        String taskDefinitionKey = nextTask.getTaskDefinitionKey();
        List<SysUser> userList = definitionNodeService.queryByTaskDefinitionKey(taskDefinitionKey);
        List<String> auditors = new ArrayList<>();
        for (SysUser sysUser : userList) {
            //给下一个任务设置候选人
            processService.addCandidateUser(nextTask, sysUser.getUserId());
            auditors.add(sysUser.getUserName());
        }

        audit.setStatus(CarPackageAudit.STATUS_IN_ROGRESS);
        audit.setAuditors(JSON.toJSONString(auditors));
        // 更新carPackageAudit对象的auditors字段
        carPackageAuditMapper.updateCarPackageAudit(audit);
    }

    @Override
    public List<CarPackageAudit> selectDoneList(CarPackageAudit carPackageAudit) {
        // 获取已办任务的总数
        long count = processService.selectDoneTaskCount(CarPackageAudit.DEFINITION_KEY, ShiroUtils.getUserId().toString());
        if (count > 0) {
            // 获取前台传入的pageNum和PageSize
            PageDomain pageDomain = TableSupport.buildPageRequest();
            Integer pageNum = pageDomain.getPageNum();
            Integer pageSize = pageDomain.getPageSize();
            List<HistoricTaskInstance> HistoricTaskList = processService
                    .selectDoneTaskList(CarPackageAudit.DEFINITION_KEY, // 流程定义Key
                            ShiroUtils.getUserId().toString(), // 用户id
                            (pageNum - 1) * pageSize, // 起始位置
                            pageSize); // 每页条数
            //3.遍历待办任务,查询对应的CarPackAgeAudit
            List<CarPackageAudit> resultList = new ArrayList<>();
            CarPackageAudit audit;
            for (HistoricTaskInstance task : HistoricTaskList) {
                // 如果任务已经完成了 processInstance 是拿不到的,因为已经流程走完了,应该用 HistoricProcessInstance
                HistoricProcessInstance historicProcessInstance = processService
                        .getHistoricProcessInstanceById(task.getProcessInstanceId());
                String businessKey = historicProcessInstance.getBusinessKey();
                audit = carPackageAuditMapper.selectCarPackageAuditById(Long.valueOf(businessKey));
                audit.setServiceItem(JSON.parseObject(audit.getServiceItemInfo(), ServiceItem.class));// JSON 字符串转成对象
                audit.setTaskName(task.getName());
                audit.setTaskId(task.getId());
                audit.setDoneTime(task.getEndTime());// 任务完成时间
                resultList.add(audit);
            }
            Page page = new Page();
            page.setTotal(count);
            page.setPageNum(pageNum);
            page.setPageSize(pageSize);
            page.addAll(resultList);
            return page;
        } else {
            return Collections.EMPTY_LIST;
        }
    }

    @Override
    public List<HistoricActivity> selectHistoryList(String instanceId) {
        // 查询集合
        List<HistoricActivityInstance> instanceList = processService.selectHistoryTaskList(instanceId);
        ArrayList<HistoricActivity> resultList = new ArrayList<>();
        //遍历集合
        for (HistoricActivityInstance instance : instanceList) {
            HistoricActivity historicActivity = new HistoricActivity();
            //拷贝属性
            BeanUtils.copyProperties(instance, historicActivity);
            //查询审核批注
            historicActivity.setComment(processService.getTaskComment(instance.getTaskId()));
            String assignee = instance.getAssignee();
            if(StringUtils.isNotEmpty(assignee)){
                SysUser sysUser = sysUserMapper.selectUserById(Long.parseLong(assignee));
                if (sysUser != null) {
                    //设置审核人姓名
                    historicActivity.setAssigneeName(sysUser.getUserName());
                }
            }
            resultList.add(historicActivity);
        }
        return resultList;
    }
}
